package com.yuntsg.nnsfcp.service.front.ut;

import com.yuntsg.nnsfcp.service.front.pojo.PinYinEntity;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 这是包含多音字的 拼音工具
 * <p>
 * PinYinUtil 是没有多音的生成, 所以继承了他的方法
 *
 * @author ：ljx
 * @date ：Created in 2019/11/5
 */
public class PinYinManyUtil extends PinYinUtil {

    private static Logger logger = LoggerFactory.getLogger(PinYinManyUtil.class);


    /**
     * 样品测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        String pinyin = getManyPinY("刘家兴");
        System.out.println(pinyin);
    }


    /**
     * 判断名字长度,调用对应方法
     *
     * @param name 中文名
     * @return
     * @throws Exception
     */
    public static String getManyPinY(String name) throws Exception {
        char[] strs = name.toCharArray();
        //名字的长度
        int nameLengthTwo = 2;
        int nameLengthThree = 3;
        int nameLengthFour = 4;

        if (strs.length == nameLengthTwo) {
            String manyPinYin = getManyPinYin(getManyEnName(name));
            if (StringUtils.isNotEmpty(manyPinYin)) {
                //返回2个字名字结果
                getTwoNames(name, manyPinYin);
            } else {
                logger.error("获取到的拼音是空的: " + name);
                logger.error("长度: " + nameLengthFour);
            }
        } else if (strs.length == nameLengthThree) {
            String manyPinYin = getManyPinYin(getManyEnName(name));
            if (StringUtils.isNotEmpty(manyPinYin)) {
                //返回3个字的名字结果
                getThreeNames(name, manyPinYin);
            } else {
                logger.error("获取到的拼音是空的: " + name);
                logger.error("长度: " + nameLengthFour);
            }
        } else if (strs.length == nameLengthFour) {
            String manyPinYin = getManyPinYin(getManyEnName(name));
            if (StringUtils.isNotEmpty(manyPinYin)) {
                //返回4个字的结果
                getFourNames(name, manyPinYin);
            } else {
                logger.error("获取到的拼音是空的: " + name);
                logger.error("长度: " + nameLengthFour);
            }
        } else {
            throw new Exception("名字长度不合法");
        }
        return str;
    }


    /**
     * 将中文转换为英文, (包含多音字)
     *
     * @param name 中文名
     * @return 获取中转拼音(包括多音字), 封装返回实体类
     * @throws Exception
     */
    private static PinYinEntity getManyEnName(String name) throws Exception {
        char[] chars = name.toCharArray();
        HanyuPinyinOutputFormat pyFormat = new HanyuPinyinOutputFormat();
        pyFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        pyFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        pyFormat.setVCharType(HanyuPinyinVCharType.WITH_V);

        PinYinEntity pinYinEntity = new PinYinEntity();
        if (chars.length == 2) {
            //姓
            char aChar = chars[0];
            String[] strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setXin(strings);
            //名
            aChar = chars[1];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin1(strings);
            pinYinEntity.setNameLength(2);
        }
        if (chars.length == 3) {
            //姓
            char aChar = chars[0];
            String[] strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setXin(strings);

            //名1
            aChar = chars[1];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin1(strings);

            //名2
            aChar = chars[2];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin2(strings);
            pinYinEntity.setNameLength(3);
        }
        if (chars.length == 4) {
            //姓
            char aChar = chars[0];
            String[] strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setXin(strings);

            //名
            aChar = chars[1];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin1(strings);

            //名
            aChar = chars[2];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin2(strings);

            //名
            aChar = chars[3];
            strings = PinyinHelper.toHanyuPinyinStringArray(aChar, pyFormat);
            pinYinEntity.setMin3(strings);
            pinYinEntity.setNameLength(4);
        }

        return pinYinEntity;
    }

    /**
     * 得到多音字的 组合字符串
     *
     * @param pinYinEntity 封装的拼音实体类
     * @return 返回 ; 号间隔的多个多音组合
     */
    private static String getManyPinYin(PinYinEntity pinYinEntity) {
        if (pinYinEntity.getNameLength() == 2) {
            StringBuilder resultBuilder = new StringBuilder();

            //处理2个字名字的
            String[] xinArr = pinYinEntity.getXin();
            String[] min1 = pinYinEntity.getMin1();

            if (xinArr.length > 1 || min1.length > 1) {
                //姓 的多音集合
                ArrayList<String> xinList = new ArrayList<>();
                Collections.addAll(xinList, xinArr);
                //名1 的多音集合
                ArrayList<String> min1List = new ArrayList<>();
                Collections.addAll(min1List, min1);
                //合成
                for (int i = 0; i < xinList.size(); i++) {
                    String xin = xinList.get(i);
                    for (int j = 0; j < min1List.size(); j++) {
                        String min = min1List.get(j);
                        resultBuilder.append(xin).append(",").append(min).append(";");
                    }
                }
            } else {
                //都不是多音字
                resultBuilder.append(xinArr[0]).append(",").append(min1[0]).append(";");
            }
            return resultBuilder.toString();
        }
        if (pinYinEntity.getNameLength() == 3) {
            StringBuilder resultBuilder = new StringBuilder();

            //处理3个字名字的
            String[] xinArr = pinYinEntity.getXin();
            String[] min1Arr = pinYinEntity.getMin1();
            String[] min2Arr = pinYinEntity.getMin2();
            if (xinArr.length > 1 || min1Arr.length > 1 || min2Arr.length > 1) {
                //姓 集合
                ArrayList<String> xinList = new ArrayList<>();
                Collections.addAll(xinList, xinArr);

                //名1 的多音集合
                ArrayList<String> min1List = new ArrayList<>();
                Collections.addAll(min1List, min1Arr);

                //名2 的多音集合
                ArrayList<String> min2List = new ArrayList<>();
                Collections.addAll(min2List, min2Arr);

                //合成
                for (int i = 0; i < xinList.size(); i++) {
                    String xin = xinList.get(i);
                    for (int j = 0; j < min1List.size(); j++) {
                        String min1 = min1List.get(j);
                        for (int k = 0; k < min2List.size(); k++) {
                            String min2 = min2List.get(k);

                            resultBuilder.append(xin).append(",").append(min1).append(",").append(min2).append(";");
                        }
                    }
                }
            } else {
                //都不是多音字
                resultBuilder.append(xinArr[0]).append(",").append(min1Arr[0]).append(",").append(min2Arr[0]).append(";");
            }
            return resultBuilder.toString();
        }
        if (pinYinEntity.getNameLength() == 4) {
            StringBuilder resultBuilder = new StringBuilder();

            //处理4个字名字的
            String[] xinArr = pinYinEntity.getXin();
            String[] min1Arr = pinYinEntity.getMin1();
            String[] min2Arr = pinYinEntity.getMin2();
            String[] min3Arr = pinYinEntity.getMin3();

            if (xinArr.length > 1 || min1Arr.length > 1 || min2Arr.length > 1 || min3Arr.length > 1) {

                //姓 集合
                ArrayList<String> xinList = new ArrayList<>();
                Collections.addAll(xinList, xinArr);

                //名1 的多音集合
                ArrayList<String> min1List = new ArrayList<>();
                Collections.addAll(min1List, min1Arr);

                //名2 的多音集合
                ArrayList<String> min2List = new ArrayList<>();
                Collections.addAll(min2List, min2Arr);

                //名3 的多音集合
                ArrayList<String> min3List = new ArrayList<>();
                Collections.addAll(min3List, min3Arr);

                //合成
                for (int i = 0; i < xinList.size(); i++) {
                    String xin = xinList.get(i);
                    for (int j = 0; j < min1List.size(); j++) {
                        String min1 = min1List.get(j);
                        for (int k = 0; k < min2List.size(); k++) {
                            String min2 = min2List.get(k);
                            for (int l = 0; l < min3List.size(); l++) {
                                String min3 = min3List.get(l);

                                resultBuilder.append(xin).append(",").append(min1).append(",").append(min2).append(",").append(min3).append(";");
                            }
                        }
                    }
                }
            } else {
                //都不是多音字
                resultBuilder.append(xinArr[0]).append(",").append(min1Arr[0]).append(",").append(min2Arr[0]).append(",").append(min3Arr[0]).append(";");
            }
            return resultBuilder.toString();
        }
        return null;
    }

    /**
     * 获取2个名字的多种格式
     *
     * @param cnName 中文名
     * @return
     * @throws Exception
     */
    private static void getTwoNames(String cnName, String enNames) throws Exception {
        StringBuffer buff = new StringBuffer();

        //多音字 ; 分号间隔的
        String[] split = enNames.split(";");
        for (String enName : split) {

            //姓与名的分隔  , 号间隔
            String[] sp = enName.split(",");
            String newName = toUpCase(sp[0]) + ", "
                    + toUpCase(sp[1]);

            //Hu Ge
            String[] splits = newName.split(", ");

            //1 Hu,Ge
            buff.append(newName).append(";");

            //2 Ge, Hu;
            buff.append(splits[1]).append(", ").append(splits[0]).append(";");

            //3 Hu,G;
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(";");

            //4 G, Hu;
            buff.append(splits[1].substring(0, 1)).append(", ").append(splits[0]).append(";");

            //5 Hu,G.;
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(".").append(";");

            // Hu Ge;
            buff.append(splits[0]).append(" ").append(splits[1]).append(";");

            // Hu-Ge;
            buff.append(splits[0]).append("-").append(splits[1]).append(";");

            // Ge Hu;
            buff.append(splits[1]).append(" ").append(splits[0]).append(";");

            // Hu G;
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append(";");

            // G Hu;
            buff.append(splits[1].substring(0, 1)).append(" ").append(splits[0]).append(";");
        }
        //14 胡歌
        buff.append(cnName);
        str = buff.toString();
    }

    /**
     * 获取3个字名字的多种格式
     *
     * @param cnName 中文名
     * @return
     */
    private static void getThreeNames(String cnName, String enNames) throws Exception {
        StringBuffer buff = new StringBuffer();

        //多音字 ; 分号间隔的
        String[] split = enNames.split(";");
        //set集合去重的, 生成的多音有重复
        Set<String> set = new HashSet<>(Arrays.asList(split));

        for (String enName : set) {

            //姓与名的分隔  , 号间隔
            String[] strs = enName.split(",");

            //这里是三段 Li yu chun
            String newName = toUpCase(strs[0]) + ", "
                    + toUpCase(strs[1]) + ", "
                    + toUpCase(strs[2]);
            String[] splits = newName.split(", ");

            //将名字分为 两个分段, Li, Yuchun
            String newName2 = toUpCase(strs[0]) + ", "
                    + toUpCase(strs[1] + strs[2]);
            String[] pinYin1 = newName2.split(", ");

            //1 Li,Yuchun
            buff.append(newName2).append(";");

            //2 Li Yuchun
            buff.append(pinYin1[0]).append(" ").append(pinYin1[1]).append(";");

            //3 Yuchun,Li
            buff.append(pinYin1[1]).append(", ").append(pinYin1[0]).append(";");

            //4 YuChun Li
            buff.append(pinYin1[1]).append(" ").append(pinYin1[0]).append(";");

            //5 Yu-Chun,Li
            buff.append(splits[2]).append("-").append(splits[1]).append(", ").append(splits[0]).append(";");

            //6 Li,Yu-Chun;
            buff.append(splits[0]).append(", ").append(splits[1]).append("-").append(splits[2]).append(";");

            //7 Li Yu-Chun;
            buff.append(splits[0]).append(" ").append(splits[1]).append("-").append(splits[2]).append(";");

            //8 Yu-Chun Li;
            buff.append(splits[2]).append("-").append(splits[1]).append(" ").append(splits[0]).append(";");

            //9 Li,Y.C.;
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(".").append(";");

            //15 Li Y.C.;
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(".").append(";");

            //18 Li Y-C;
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append("-").append(splits[2].substring(0, 1)).append(";");

            //19 Li, Y-C;
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append("-").append(splits[2].substring(0, 1)).append(";");

            //16 Li Y.C;
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(";");

            //17 Li, Y.C;
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(";");

            //10 Li YC;
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(";");

            //11 Li,YC
            buff.append(splits[0]).append(",").append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(";");

            //12 YC Li;
            buff.append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(" ").append(splits[0]).append(";");

            // Y-C Li;
            buff.append(splits[1].substring(0, 1)).append("-").append(splits[2].substring(0, 1)).append(" ").append(splits[0]).append(";");

            // Y-C, Li;
            buff.append(splits[1].substring(0, 1)).append("-").append(splits[2].substring(0, 1)).append(", ").append(splits[0]).append(";");

            //13 YC,Li;
            buff.append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(", ").append(splits[0]).append(";");

            // Y.C,Li;
            buff.append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(", ").append(splits[0]).append(";");

            // Y.C. Li;
            buff.append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(". ").append(splits[0]).append(";");

            // Y.C Li;
            buff.append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(" ").append(splits[0]).append(";");

            // Y.C., Li;
            buff.append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append("., ").append(splits[0]).append(";");
        }
        //14 李宇春
        buff.append(cnName);
        str = buff.toString();
    }

    /**
     * 获取4个字名字的多种格式
     *
     * @param cnName 中文名
     * @return
     * @throws Exception
     */
    private static void getFourNames(String cnName, String enNames) throws Exception {
        StringBuffer buff = new StringBuffer();

        //多音字 ; 分号间隔的
        String[] split = enNames.split(";");
        for (String enName : split) {
            //姓与名的分隔  , 号间隔
            String[] strs = enName.split(",");

            //这里是三段
            String newName = toUpCase(strs[0]) + ", "
                    + toUpCase(strs[1]) + ", "
                    + toUpCase(strs[2]) + ", "
                    + toUpCase(strs[3]);
            String[] splits = newName.split(", ");

            //将名字分为 两个分段, Di Lireba
            String newName2 = toUpCase(strs[0]) + ", "
                    + toUpCase(strs[1] + strs[2] + strs[3]);
            String[] pinYin1 = newName2.split(", ");

            //Di，Lireba；
            buff.append(newName2).append(";");

            // Lireba，Di；
            buff.append(pinYin1[1]).append(", ").append(pinYin1[0]).append(";");

            // Di，Li-Re-Ba；
            buff.append(splits[0]).append(", ").append(splits[1]).append("-").append(splits[2]).append("-").append(splits[3]).append(";");

            // Li-Re-Ba，Di；
            buff.append(splits[1]).append("-").append(splits[2]).append("-").append(splits[3]).append(", ").append(splits[0]).append(";");

            // Di，LRB；
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(splits[3].substring(0, 1)).append(";");

            // LRB，Di；
            buff.append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(splits[3].substring(0, 1)).append(", ").append(splits[0]).append(";");

            // Di，L.R.B.；
            buff.append(splits[0]).append(", ").append(splits[1].substring(0, 1)).append(".").append(splits[2].substring(0, 1)).append(".").append(splits[3].substring(0, 1)).append(".").append(";");

            // Di Lireba；
            buff.append(pinYin1[0]).append(" ").append(pinYin1[1]).append(";");

            // Lireba Di；
            buff.append(pinYin1[1]).append(" ").append(pinYin1[0]).append(";");

            // Di Li-Re-Ba；
            buff.append(splits[0]).append(" ").append(splits[1]).append("-").append(splits[2]).append("-").append(splits[3]).append(";");

            // Li-Re-Ba Di；
            buff.append(splits[1]).append("-").append(splits[2]).append("-").append(splits[3]).append(" ").append(splits[0]).append(";");

            // Di LRB；
            buff.append(splits[0]).append(" ").append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(splits[3].substring(0, 1)).append(";");

            // Di,LRB
            buff.append(splits[0]).append(",").append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(splits[3].substring(0, 1)).append(";");

            // LRB Di；
            buff.append(splits[1].substring(0, 1)).append(splits[2].substring(0, 1)).append(splits[3].substring(0, 1)).append(" ").append(splits[0]).append(";");
        }
        // 迪丽热巴
        buff.append(cnName);
        str = buff.toString();
    }
}
